/*
 * Systemprogrammierung
 * Multiplayer-Quiz
 *
 * Server
 *
 * login.c: Implementierung des Logins
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include "login.h"
#include "clientthread.h"
#include "common/util.h"
#include "common/rfc.h"
#include "clientthread.h"

int iListeningPort = 0;
int iSpielphaseAktiv = 0;

void login_StartLoginThread(int iPort) {
	if (iPort > 0) {
		iListeningPort = iPort;
	} else {
		iListeningPort = atoi(TCP_DEFAULT_PORT);
	}
	infoPrint("\nUebergebe zu Listener-Thread");
	login_WorkerLoginThread();
}

void login_WorkerLoginThread() {
	login_ServerListeningLoop();

	return;
}

void login_ServerListeningLoop() {
	int iTemp;
	char sTemp[512];

	int iPort;
	int iListeningSocket, iNewClientSocket;
	static char sBuffer[512];
	socklen_t iNewClientLength;
	struct sockaddr_in oServerAddress, oSocket_ClientAddress;

	iListeningSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (iListeningSocket < 0) {
    	errorPrint("\nError opening listener-socket");
    }
    else {
        bzero((char *) &oServerAddress, sizeof(oServerAddress));
        oServerAddress.sin_family = AF_INET;
        oServerAddress.sin_addr.s_addr = INADDR_ANY;
        oServerAddress.sin_port = htons(iListeningPort);

        if (bind(iListeningSocket, (struct sockaddr *) &oServerAddress, sizeof(oServerAddress)) < 0) {
        	errorPrint("\nError binding listener-socket");
        }
        else {
        	///////////////////////////////////
        	// ##### Listener Schleife ##### //
        	///////////////////////////////////
        	while (1) {
        		// Listen
        		infoPrint("\nStarting to listen on port %i", iListeningPort);
                listen(iListeningSocket, 5);

                // Accept new connections
                iNewClientLength = sizeof(oSocket_ClientAddress);
                iNewClientSocket = accept(iListeningSocket, (struct sockaddr *) &oSocket_ClientAddress, &iNewClientLength);
                if (iNewClientSocket < 0) {
                	errorPrint("\nERROR on accepting new connection");
                }
                else {
                	infoPrint("\nNew client connection successfully accepted!");

                	// Check phase
                    if (iSpielphaseAktiv == 1) {
                    	// Send error and destroy connection
                    	server_SendErrorMessage(iNewClientSocket, "Fehler: Spielphase bereits aktiv", 1);
                    	close(iNewClientSocket);
                    } else {
                    	// Create login thread
                    	clientt_CreateClientThread(iNewClientSocket);
                    }
                }
        	}
        }
    }

	return;

}

void login_SetSpielphase(int iAktiv) {
	iSpielphaseAktiv = iAktiv;
}

int login_GetSpielphase() {
	return iSpielphaseAktiv;
}
